<!DOCTYPE HTML>
<!--
	Dimension by HTML5 UP
	html5up.net | @ajlkn
	Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
-->
<html>
 <head>
  <title>
   Dimension by HTML5 UP
  </title>
  <!-- <meta charset="utf-8" /> -->
  <!-- <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" /> -->
  <meta charset="utf-8"/>
  <meta content="width=device-width,initial-scale=1.0" name="viewport"/>
  <link href="../../assets/css/article.css" rel="stylesheet"/>
  <link href="https://cdn.bootcss.com/highlight.js/9.15.8/styles/github.min.css" rel="stylesheet"/>
  <noscript>
   <link href="../../assets/css/noscript.css" rel="stylesheet"/>
  </noscript>
 </head>
 <body>
  <div id="app">
  </div>
  <!-- built files will be auto injected -->
 </body>
 <body class="is-preload">
  <!-- Wrapper -->
  <div id="wrapper">
   <!-- Main -->
   <div id="main">
    <article id="article">
     <h1 id="mybatis-demo-1">
      MyBatis Demo 编写（1）基础功能搭建
     </h1>
     <hr/>
     <p>
      这是我参与2022首次更文挑战的第16天，活动详情查看：
      <a href="https://juejin.cn/post/7052884569032392740">
       2022首次更文挑战
      </a>
     </p>
     <h2 id="_1">
      简介
     </h2>
     <p>
      在Mybatis3的源码解析系列中，我们对其核心功能有了一定的了解，下面我们尝试简单写一下Demo，让其有简单的Mybatis的一些核心功能，本篇是基础功能的搭建
     </p>
     <h2 id="dome">
      Dome 编写
     </h2>
     <p>
      完整的工程已放到GitHub上：https://github.com/lw1243925457/MybatisDemo/tree/master/
     </p>
     <p>
      本篇文章的代码对应的Tag是: V1
     </p>
     <p>
      本篇的目标是完成MapperProxy和运行不带参数和无自定义返回类型的SQL
     </p>
     <p>
      测试代码如下：
     </p>
     <div class="codehilite">
      <pre><span></span><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">SelfMybatisTest</span> <span class="p">{</span>

    <span class="nd">@Test</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">test</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">try</span><span class="p">(</span><span class="n">SelfSqlSession</span> <span class="n">session</span> <span class="o">=</span> <span class="n">buildSqlSessionFactory</span><span class="p">())</span> <span class="p">{</span>
            <span class="n">PersonMapper</span> <span class="n">personMapper</span> <span class="o">=</span> <span class="n">session</span><span class="p">.</span><span class="na">getMapper</span><span class="p">(</span><span class="n">PersonMapper</span><span class="p">.</span><span class="na">class</span><span class="p">);</span>
            <span class="n">personMapper</span><span class="p">.</span><span class="na">createTable</span><span class="p">();</span>
            <span class="n">personMapper</span><span class="p">.</span><span class="na">save</span><span class="p">();</span>
            <span class="n">List</span><span class="o">&lt;</span><span class="n">Object</span><span class="o">&gt;</span> <span class="n">personList</span> <span class="o">=</span> <span class="n">personMapper</span><span class="p">.</span><span class="na">list</span><span class="p">();</span>
            <span class="k">for</span> <span class="p">(</span><span class="n">Object</span> <span class="n">person</span><span class="p">:</span> <span class="n">personList</span><span class="p">)</span> <span class="p">{</span>
                <span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="n">person</span><span class="p">.</span><span class="na">toString</span><span class="p">());</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="n">SelfSqlSession</span> <span class="nf">buildSqlSessionFactory</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">String</span> <span class="n">JDBC_DRIVER</span> <span class="o">=</span> <span class="s">"org.h2.Driver"</span><span class="p">;</span>
        <span class="n">String</span> <span class="n">DB_URL</span> <span class="o">=</span> <span class="s">"jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"</span><span class="p">;</span>
        <span class="n">String</span> <span class="n">USER</span> <span class="o">=</span> <span class="s">"sa"</span><span class="p">;</span>
        <span class="n">String</span> <span class="n">PASS</span> <span class="o">=</span> <span class="s">""</span><span class="p">;</span>

        <span class="n">HikariConfig</span> <span class="n">config</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HikariConfig</span><span class="p">();</span>
        <span class="n">config</span><span class="p">.</span><span class="na">setJdbcUrl</span><span class="p">(</span><span class="n">DB_URL</span><span class="p">);</span>
        <span class="n">config</span><span class="p">.</span><span class="na">setUsername</span><span class="p">(</span><span class="n">USER</span><span class="p">);</span>
        <span class="n">config</span><span class="p">.</span><span class="na">setPassword</span><span class="p">(</span><span class="n">PASS</span><span class="p">);</span>
        <span class="n">config</span><span class="p">.</span><span class="na">setDriverClassName</span><span class="p">(</span><span class="n">JDBC_DRIVER</span><span class="p">);</span>
        <span class="n">config</span><span class="p">.</span><span class="na">addDataSourceProperty</span><span class="p">(</span><span class="s">"cachePrepStmts"</span><span class="p">,</span> <span class="s">"true"</span><span class="p">);</span>
        <span class="n">config</span><span class="p">.</span><span class="na">addDataSourceProperty</span><span class="p">(</span><span class="s">"prepStmtCacheSize"</span><span class="p">,</span> <span class="s">"250"</span><span class="p">);</span>
        <span class="n">config</span><span class="p">.</span><span class="na">addDataSourceProperty</span><span class="p">(</span><span class="s">"prepStmtCacheSqlLimit"</span><span class="p">,</span> <span class="s">"2048"</span><span class="p">);</span>
        <span class="n">DataSource</span> <span class="n">dataSource</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HikariDataSource</span><span class="p">(</span><span class="n">config</span><span class="p">);</span>

        <span class="n">SelfConfiguration</span> <span class="n">configuration</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SelfConfiguration</span><span class="p">(</span><span class="n">dataSource</span><span class="p">);</span>
<span class="c1">//        configuration.getTypeHandlerRegistry().register(String[].class, JdbcType.VARCHAR, StringArrayTypeHandler.class);</span>
        <span class="n">configuration</span><span class="p">.</span><span class="na">addMapper</span><span class="p">(</span><span class="n">PersonMapper</span><span class="p">.</span><span class="na">class</span><span class="p">);</span>
        <span class="k">return</span> <span class="k">new</span> <span class="n">SelfSqlSession</span><span class="p">(</span><span class="n">configuration</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
     </div>
     <p>
      如上所示，我们集成其他DataSource，这里使用HikariCP，然后初始化Mapper，生成表、插入、查询
     </p>
     <p>
      最终的结果如下：
     </p>
     <p>
      初始化我们的PersonMapper，最后输出查询的结果
     </p>
     <div class="codehilite">
      <pre><span></span><code>add sql source: mapper.mapper.PersonMapper.list
add sql source: mapper.mapper.PersonMapper.save
add sql source: mapper.mapper.PersonMapper.createTable

executor
executor
executor

[1, 1]
</code></pre>
     </div>
     <p>
      基本达到了要求，下面开始讲解核心代码：
     </p>
     <h3 id="mapper">
      Mapper初始化
     </h3>
     <p>
      我们的思路目前是：
     </p>
     <ul>
      <li>
       1.SelfConfiguration 作为全局配置类，从中取得DataSource和Mapper相关的信息（目前是接口方法对应的SQL语句）
      </li>
      <li>
       2.SelfConfiguration 构造函数保存DataSource
      </li>
      <li>
       3.SelfConfiguration 添加Mapper时，保存其中方式对应的SQL语句信息到Map，方法的路径作为唯一标识
      </li>
     </ul>
     <p>
      SelfConfiguration 相关的代码
     </p>
     <div class="codehilite">
      <pre><span></span><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">SelfConfiguration</span> <span class="p">{</span>

    <span class="kd">private</span> <span class="kd">final</span> <span class="n">DataSource</span> <span class="n">dataSource</span><span class="p">;</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">SqlSource</span><span class="o">&gt;</span> <span class="n">sqlCache</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HashMap</span><span class="o">&lt;&gt;</span><span class="p">();</span>

    <span class="kd">public</span> <span class="nf">SelfConfiguration</span><span class="p">(</span><span class="n">DataSource</span> <span class="n">dataSource</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="na">dataSource</span> <span class="o">=</span> <span class="n">dataSource</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="cm">/**</span>
<span class="cm">     * Mapper添加</span>
<span class="cm">     * 保存接口方法的SQL类型和方法</span>
<span class="cm">     * 方法路径作为唯一的id</span>
<span class="cm">     * @param mapperClass mapper</span>
<span class="cm">     */</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">addMapper</span><span class="p">(</span><span class="n">Class</span><span class="o">&lt;?&gt;</span> <span class="n">mapperClass</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">final</span> <span class="n">String</span> <span class="n">classPath</span> <span class="o">=</span> <span class="n">mapperClass</span><span class="p">.</span><span class="na">getPackageName</span><span class="p">();</span>
        <span class="kd">final</span> <span class="n">String</span> <span class="n">className</span> <span class="o">=</span> <span class="n">mapperClass</span><span class="p">.</span><span class="na">getName</span><span class="p">();</span>
        <span class="k">for</span> <span class="p">(</span><span class="n">Method</span> <span class="n">method</span><span class="p">:</span> <span class="n">mapperClass</span><span class="p">.</span><span class="na">getMethods</span><span class="p">())</span> <span class="p">{</span>
            <span class="kd">final</span> <span class="n">String</span> <span class="n">id</span> <span class="o">=</span> <span class="n">StringUtils</span><span class="p">.</span><span class="na">joinWith</span><span class="p">(</span><span class="s">"."</span> <span class="p">,</span><span class="n">classPath</span><span class="p">,</span> <span class="n">className</span><span class="p">,</span> <span class="n">method</span><span class="p">.</span><span class="na">getName</span><span class="p">());</span>
            <span class="k">for</span> <span class="p">(</span><span class="n">Annotation</span> <span class="n">annotation</span><span class="p">:</span> <span class="n">method</span><span class="p">.</span><span class="na">getAnnotations</span><span class="p">())</span> <span class="p">{</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">annotation</span> <span class="k">instanceof</span> <span class="n">Select</span><span class="p">)</span> <span class="p">{</span>
                    <span class="n">addSqlSource</span><span class="p">(</span><span class="n">id</span><span class="p">,</span> <span class="p">((</span><span class="n">Select</span><span class="p">)</span> <span class="n">annotation</span><span class="p">).</span><span class="na">value</span><span class="p">(),</span> <span class="n">SqlType</span><span class="p">.</span><span class="na">SELECT</span><span class="p">);</span>
                    <span class="k">continue</span><span class="p">;</span>
                <span class="p">}</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">annotation</span> <span class="k">instanceof</span> <span class="n">Insert</span><span class="p">)</span> <span class="p">{</span>
                    <span class="n">addSqlSource</span><span class="p">(</span><span class="n">id</span><span class="p">,</span> <span class="p">((</span><span class="n">Insert</span><span class="p">)</span> <span class="n">annotation</span><span class="p">).</span><span class="na">value</span><span class="p">(),</span> <span class="n">SqlType</span><span class="p">.</span><span class="na">INSERT</span><span class="p">);</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="kd">private</span> <span class="kt">void</span> <span class="nf">addSqlSource</span><span class="p">(</span><span class="kd">final</span> <span class="n">String</span> <span class="n">id</span><span class="p">,</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">sql</span><span class="p">,</span> <span class="kd">final</span> <span class="n">SqlType</span> <span class="n">selectType</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">"add sql source: "</span> <span class="o">+</span> <span class="n">id</span><span class="p">);</span>
        <span class="kd">final</span> <span class="n">SqlSource</span> <span class="n">sqlSource</span> <span class="o">=</span> <span class="n">SqlSource</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span>
                <span class="p">.</span><span class="na">type</span><span class="p">(</span><span class="n">selectType</span><span class="p">)</span>
                <span class="p">.</span><span class="na">sql</span><span class="p">(</span><span class="n">sql</span><span class="p">)</span>
                <span class="p">.</span><span class="na">build</span><span class="p">();</span>
        <span class="n">sqlCache</span><span class="p">.</span><span class="na">put</span><span class="p">(</span><span class="n">id</span><span class="p">,</span> <span class="n">sqlSource</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="kd">public</span> <span class="n">DataSource</span> <span class="nf">getDataSource</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="n">dataSource</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="kd">public</span> <span class="n">SqlSource</span> <span class="nf">getSqlSource</span><span class="p">(</span><span class="kd">final</span> <span class="n">String</span> <span class="n">id</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">sqlCache</span><span class="p">.</span><span class="na">containsKey</span><span class="p">(</span><span class="n">id</span><span class="p">))</span> <span class="p">{</span>
            <span class="k">return</span> <span class="n">sqlCache</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">id</span><span class="p">);</span>
        <span class="p">}</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="n">RuntimeException</span><span class="p">(</span><span class="s">"don't find mapper match: "</span> <span class="o">+</span> <span class="n">id</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
     </div>
     <h3 id="mapperproxy">
      MapperProxy生成
     </h3>
     <p>
      MapperProxy 从 SelfSqlSession 中进行获取，MapperProxy中调用Executor的方法即可，比较简单
     </p>
     <p>
      SelfSqlSession 主要是返回MapperProxy
     </p>
     <div class="codehilite">
      <pre><span></span><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">SelfSqlSession</span> <span class="kd">implements</span> <span class="n">Closeable</span> <span class="p">{</span>

    <span class="kd">private</span> <span class="kd">final</span> <span class="n">SelfConfiguration</span> <span class="n">config</span><span class="p">;</span>

    <span class="kd">public</span> <span class="nf">SelfSqlSession</span><span class="p">(</span><span class="n">SelfConfiguration</span> <span class="n">configuration</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="na">config</span> <span class="o">=</span> <span class="n">configuration</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">close</span><span class="p">()</span> <span class="p">{</span>
    <span class="p">}</span>

    <span class="kd">public</span> <span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">T</span> <span class="nf">getMapper</span><span class="p">(</span><span class="n">Class</span><span class="o">&lt;?&gt;</span> <span class="n">mapperClass</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">final</span> <span class="n">MapperProxy</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">proxy</span> <span class="o">=</span> <span class="k">new</span> <span class="n">MapperProxy</span><span class="p">(</span><span class="n">config</span><span class="p">);</span>
        <span class="k">return</span> <span class="p">(</span><span class="n">T</span><span class="p">)</span> <span class="n">Proxy</span><span class="p">.</span><span class="na">newProxyInstance</span><span class="p">(</span><span class="n">mapperClass</span><span class="p">.</span><span class="na">getClassLoader</span><span class="p">(),</span> <span class="k">new</span> <span class="n">Class</span><span class="o">[]</span> <span class="p">{</span><span class="n">mapperClass</span><span class="p">},</span> <span class="n">proxy</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
     </div>
     <p>
      MapperProxy 简单调用下 Executor
     </p>
     <div class="codehilite">
      <pre><span></span><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">MapperProxy</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="kd">implements</span> <span class="n">InvocationHandler</span> <span class="p">{</span>

    <span class="kd">private</span> <span class="kd">final</span> <span class="n">SelfConfiguration</span> <span class="n">config</span><span class="p">;</span>

    <span class="kd">public</span> <span class="nf">MapperProxy</span><span class="p">(</span><span class="kd">final</span> <span class="n">SelfConfiguration</span> <span class="n">configuration</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="na">config</span> <span class="o">=</span> <span class="n">configuration</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="n">Object</span> <span class="nf">invoke</span><span class="p">(</span><span class="n">Object</span> <span class="n">proxy</span><span class="p">,</span> <span class="n">Method</span> <span class="n">method</span><span class="p">,</span> <span class="n">Object</span><span class="o">[]</span> <span class="n">args</span><span class="p">)</span> <span class="kd">throws</span> <span class="n">Throwable</span> <span class="p">{</span>
        <span class="k">return</span> <span class="n">Executor</span><span class="p">.</span><span class="na">executor</span><span class="p">(</span><span class="n">config</span><span class="p">,</span> <span class="n">proxy</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="n">args</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
     </div>
     <h3 id="sql">
      SQL语句执行
     </h3>
     <p>
      主要逻辑如下：
     </p>
     <ul>
      <li>
       SQL的编排主要还是在Executor中
      </li>
      <li>
       语句的解析和执行在StatementHandler中，返回返回结果
      </li>
      <li>
       结果的解析在ResultHandler中
      </li>
     </ul>
     <p>
      Executor 代码如下，获取数据库连接，StatementHandler执行，ResultHandler处理结果返回
     </p>
     <div class="codehilite">
      <pre><span></span><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Executor</span> <span class="p">{</span>

    <span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">StatementHandler</span> <span class="n">statementHandler</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StatementHandler</span><span class="p">();</span>
    <span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">ResultHandler</span> <span class="n">resultHandler</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ResultHandler</span><span class="p">();</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="n">Object</span> <span class="nf">executor</span><span class="p">(</span><span class="n">SelfConfiguration</span> <span class="n">config</span><span class="p">,</span> <span class="n">Object</span> <span class="n">proxy</span><span class="p">,</span> <span class="n">Method</span> <span class="n">method</span><span class="p">,</span> <span class="n">Object</span><span class="o">[]</span> <span class="n">args</span><span class="p">)</span> <span class="kd">throws</span> <span class="n">SQLException</span> <span class="p">{</span>
        <span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">"executor"</span><span class="p">);</span>
        <span class="k">try</span> <span class="p">(</span><span class="n">Connection</span> <span class="n">conn</span> <span class="o">=</span> <span class="n">config</span><span class="p">.</span><span class="na">getDataSource</span><span class="p">().</span><span class="na">getConnection</span><span class="p">())</span> <span class="p">{</span>
            <span class="n">ResultSet</span> <span class="n">resultSet</span> <span class="o">=</span> <span class="n">statementHandler</span><span class="p">.</span><span class="na">prepare</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">proxy</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">config</span><span class="p">);</span>
            <span class="k">return</span> <span class="n">resultHandler</span><span class="p">.</span><span class="na">parse</span><span class="p">(</span><span class="n">resultSet</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
     </div>
     <p>
      StetementHandler主要是从Config从获取需要执行的SQL信息
     </p>
     <p>
      目前比较简单，根据SQL类型，直接执行即可
     </p>
     <div class="codehilite">
      <pre><span></span><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">StatementHandler</span> <span class="p">{</span>

    <span class="kd">public</span> <span class="n">ResultSet</span> <span class="nf">prepare</span><span class="p">(</span><span class="n">Connection</span> <span class="n">conn</span><span class="p">,</span> <span class="n">Object</span> <span class="n">proxy</span><span class="p">,</span> <span class="n">Method</span> <span class="n">method</span><span class="p">,</span> <span class="n">Object</span><span class="o">[]</span> <span class="n">args</span><span class="p">,</span> <span class="n">SelfConfiguration</span> <span class="n">config</span><span class="p">)</span> <span class="kd">throws</span> <span class="n">SQLException</span> <span class="p">{</span>
        <span class="kd">final</span> <span class="n">String</span> <span class="n">classPath</span> <span class="o">=</span> <span class="n">method</span><span class="p">.</span><span class="na">getDeclaringClass</span><span class="p">().</span><span class="na">getPackageName</span><span class="p">();</span>
        <span class="kd">final</span> <span class="n">String</span> <span class="n">className</span> <span class="o">=</span> <span class="n">method</span><span class="p">.</span><span class="na">getDeclaringClass</span><span class="p">().</span><span class="na">getName</span><span class="p">();</span>
        <span class="kd">final</span> <span class="n">String</span> <span class="n">methodName</span> <span class="o">=</span> <span class="n">method</span><span class="p">.</span><span class="na">getName</span><span class="p">();</span>
        <span class="kd">final</span> <span class="n">String</span> <span class="n">id</span> <span class="o">=</span> <span class="n">StringUtils</span><span class="p">.</span><span class="na">joinWith</span><span class="p">(</span><span class="s">"."</span><span class="p">,</span> <span class="n">classPath</span><span class="p">,</span> <span class="n">className</span><span class="p">,</span> <span class="n">methodName</span><span class="p">);</span>
        <span class="kd">final</span> <span class="n">SqlSource</span> <span class="n">sqlSource</span> <span class="o">=</span> <span class="n">config</span><span class="p">.</span><span class="na">getSqlSource</span><span class="p">(</span><span class="n">id</span><span class="p">);</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">sqlSource</span><span class="p">.</span><span class="na">getType</span><span class="p">().</span><span class="na">equals</span><span class="p">(</span><span class="n">SqlType</span><span class="p">.</span><span class="na">SELECT</span><span class="p">))</span> <span class="p">{</span>
            <span class="k">return</span> <span class="n">select</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">sqlSource</span><span class="p">);</span>
        <span class="p">}</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">sqlSource</span><span class="p">.</span><span class="na">getType</span><span class="p">().</span><span class="na">equals</span><span class="p">(</span><span class="n">SqlType</span><span class="p">.</span><span class="na">INSERT</span><span class="p">))</span> <span class="p">{</span>
            <span class="k">return</span> <span class="n">insert</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">sqlSource</span><span class="p">);</span>
        <span class="p">}</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="n">RuntimeException</span><span class="p">(</span><span class="s">"don't support this sql type"</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="kd">private</span> <span class="n">ResultSet</span> <span class="nf">insert</span><span class="p">(</span><span class="n">Connection</span> <span class="n">conn</span><span class="p">,</span> <span class="n">SqlSource</span> <span class="n">sqlSource</span><span class="p">)</span> <span class="kd">throws</span> <span class="n">SQLException</span> <span class="p">{</span>
        <span class="kd">final</span> <span class="n">Statement</span> <span class="n">statement</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="na">createStatement</span><span class="p">();</span>
        <span class="n">statement</span><span class="p">.</span><span class="na">execute</span><span class="p">(</span><span class="n">sqlSource</span><span class="p">.</span><span class="na">getSql</span><span class="p">());</span>
        <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="kd">private</span> <span class="n">ResultSet</span> <span class="nf">select</span><span class="p">(</span><span class="n">Connection</span> <span class="n">conn</span><span class="p">,</span> <span class="n">SqlSource</span> <span class="n">sqlSource</span><span class="p">)</span> <span class="kd">throws</span> <span class="n">SQLException</span> <span class="p">{</span>
        <span class="kd">final</span> <span class="n">Statement</span> <span class="n">statement</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="na">createStatement</span><span class="p">();</span>
        <span class="k">return</span> <span class="n">statement</span><span class="p">.</span><span class="na">executeQuery</span><span class="p">(</span><span class="n">sqlSource</span><span class="p">.</span><span class="na">getSql</span><span class="p">());</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
     </div>
     <p>
      ResultHandler 目前就是循环读取结果，然后返回
     </p>
     <div class="codehilite">
      <pre><span></span><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ResultHandler</span> <span class="p">{</span>

    <span class="kd">public</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">Object</span><span class="o">&gt;</span> <span class="nf">parse</span><span class="p">(</span><span class="n">ResultSet</span> <span class="n">res</span><span class="p">)</span> <span class="kd">throws</span> <span class="n">SQLException</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="kd">final</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">Object</span><span class="o">&gt;</span> <span class="n">list</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ArrayList</span><span class="o">&lt;&gt;</span><span class="p">(</span><span class="n">res</span><span class="p">.</span><span class="na">getFetchSize</span><span class="p">());</span>
        <span class="kd">final</span> <span class="n">ResultSetMetaData</span> <span class="n">metaData</span> <span class="o">=</span> <span class="n">res</span><span class="p">.</span><span class="na">getMetaData</span><span class="p">();</span>
        <span class="k">while</span> <span class="p">(</span><span class="n">res</span><span class="p">.</span><span class="na">next</span><span class="p">())</span> <span class="p">{</span>
            <span class="kd">final</span> <span class="kt">int</span> <span class="n">count</span> <span class="o">=</span><span class="n">metaData</span><span class="p">.</span><span class="na">getColumnCount</span><span class="p">();</span>
            <span class="kd">final</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">Object</span><span class="o">&gt;</span> <span class="n">val</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ArrayList</span><span class="o">&lt;&gt;</span><span class="p">(</span><span class="n">count</span><span class="p">);</span>
            <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="n">count</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
                <span class="kd">final</span> <span class="n">String</span> <span class="n">name</span> <span class="o">=</span> <span class="n">metaData</span><span class="p">.</span><span class="na">getColumnName</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
                <span class="kd">final</span> <span class="n">Object</span> <span class="n">value</span> <span class="o">=</span> <span class="n">res</span><span class="p">.</span><span class="na">getObject</span><span class="p">(</span><span class="n">name</span><span class="p">);</span>
                <span class="n">val</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">value</span><span class="p">);</span>
            <span class="p">}</span>
            <span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">val</span><span class="p">);</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="n">list</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
     </div>
     <h2 id="_2">
      总结
     </h2>
     <p>
      本篇中搭建了MyBatis Demo的基础部分，除了结果返回有点不好看，其他有了点日常MyBatis的味道了，结果处理后面也会完善上去
     </p>
    </article>
   </div>
   <!-- Footer -->
   <footer id="footer">
    <p class="copyright">
     © Untitled. Design:
     <a href="https://html5up.net">
      HTML5 UP
     </a>
     .
    </p>
   </footer>
  </div>
  <!-- BG -->
  <div id="bg">
  </div>
  <!-- Scripts -->
  <script src="../assets/js/jquery.min.js">
  </script>
  <script src="../assets/js/browser.min.js">
  </script>
  <script src="../assets/js/breakpoints.min.js">
  </script>
  <script src="../assets/js/util.js">
  </script>
  <script src="../assets/js/main.js">
  </script>
 </body>
</html>
